package cn.rulian.base.auth.controller;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletResponse;

import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.Colour;
import jxl.format.VerticalAlignment;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.rulian.base.auth.bo.Resource;
import cn.rulian.base.auth.bo.ResourceType;
import cn.rulian.base.auth.bo.Role;
import cn.rulian.base.auth.bo.User;
import cn.rulian.base.auth.service.ResourceService;
import cn.rulian.base.auth.service.RoleService;
import cn.rulian.base.auth.service.UserService;
import cn.rulian.base.auth.vo.RoleVo;
import cn.rulian.base.common.dto.CommonDto;
import cn.rulian.base.common.dto.ExcelBook;
import cn.rulian.base.common.dto.ExcelSheet;
import cn.rulian.base.common.dto.Message;
import cn.rulian.base.common.interceptor.AuthInterceptor;
import cn.rulian.base.common.util.xx;
import cn.rulian.base.common.vo.Result;

/**
 * 角色管理 Controller
 */

@Controller
@RequestMapping("/base/auth/role")
public class RoleController {
	
	@Autowired
	private RoleService service;
	
	@Autowired
	private ResourceService resourceService;
	
	@Autowired
	private UserService userService;
	
	private final String path="base/auth/role_"; //页面基本路径

	/**
	 * 页面基本路径
	 */
	private String getPath()
	{
		return path;
	}
	
	/**
	 * 列表页面
	 */
	@RequestMapping("/listPage")
	public String listPage() {
		return this.getPath()+"list";
	}

	/**
	 * 查询
	 */
	@RequestMapping("/listData")
	@ResponseBody
	public Result listData(RoleVo vo) {
		return service.query(vo);
	}
	
	/**
	 * 查询所有数据,供下拉列表使用。
	 */
	@RequestMapping("/findAllForselect")
	@ResponseBody
	public List<Role> findAllForselect() {
		Sort sort = new Sort(Direction.ASC, "orderNum"); // 排序
		List<Role> list = service.findAll(sort);
		return list;
	}


	/**
	 * 增加页面
	 */
	@RequestMapping("/addPage")
	public String addPage() {
		return this.getPath()+"add";
	}

	/**
	 * 增加
	 */
	@RequestMapping("/add")
	@ResponseBody
	public Message add(RoleVo vo) {
		Message rm = new Message();
		Role bo = vo.getObj();
		try {
			
			service.save(bo);
			
			rm.setMsg("保存成功！");
			rm.setCode(Message._SUCCESS);
		} catch (Exception e) {
			rm.setMsg("保存失败，异常信息：<br/>" + e.toString());
			rm.setCode(Message._ERROR);
			e.printStackTrace();
		}
		return rm;
	}

	/**
	 * 修改页面
	 */
	@RequestMapping("/updatePage")
	public String updatePage(Model model, Long id) {
		model.addAttribute("bo", service.findOne(id));
		return this.getPath()+"update";
	}

	/**
	 * 修改
	 */
	@RequestMapping("/update")
	@ResponseBody
	public Message update(RoleVo vo,Long id) {
		Message rm = new Message();
		try {
			Role obj = vo.getObj();
			Role bo = service.findOne(id);
			String oldName = bo.getName(); //旧的名称
			
			bo.setName(obj.getName());
			bo.setOrderNum(obj.getOrderNum());
			service.save(bo);
			
			//名称改变，则更新相关用户的roleNames属性
			if(!bo.getName().equals(oldName))
			{
				List<User> list = bo.getUserList();
				Set<User> needUpdateSet =new HashSet<>(); 
				needUpdateSet.addAll(list);
				this.updateUserRoleNames(needUpdateSet);
			}
			
			rm.setMsg("保存成功！");
			rm.setCode(Message._SUCCESS);
		} catch (Exception e) {
			rm.setMsg("保存失败，异常信息：<br/>" + e.toString());
			rm.setCode(Message._ERROR);
			e.printStackTrace();
		}
		return rm;
	}
	

	/**
	 * 权限配置页面
	 */
	@RequestMapping("/editAuthPage")
	public String editAuthPage(Model model, Long roleId) {
		model.addAttribute("roleId", roleId);
		return this.getPath()+"editAuth";
	}
	
	
	/**
	 * 查询所有资源数据（权限设置）
	 */
	@RequestMapping("/findAllResource")
	@ResponseBody
	public Result findAllResource(Long roleId) {
		Sort sort = new Sort(Direction.ASC, "orderNum"); // 排序
		List<Resource> list = resourceService.findAll(sort);
		
		List<Resource> menuList = new ArrayList<>(); //菜单列表
		Map<Long,List<CommonDto>> map = new HashMap<>(); //按钮map
		
		//角色已选中的资源
		List<Resource> selectList = new ArrayList<>();
		if(roleId!=null)
		{
			Role role = service.findOne(roleId);
			if(role != null)
			{
				selectList = role.getResourceList();
			}
		}
		
		for(Resource bo:list)
		{
			Boolean enabled = bo.getEnabled();
			
			//有效性判断
			if(enabled!=null && !enabled.booleanValue())
			{
				continue;
			}
			
			//相关展示属性处理
			if(bo.getFather() != null)
			{
				bo.set_parentId(bo.getFather().getId());
			}
			bo.setRoleList(null);
			bo.setFather(null);
			
			for(Resource one : selectList)
			{
				if(bo.getId().longValue() == one.getId().longValue())
				{
					bo.setChecked(true);
					break;
				}
			}
			
			//处理按钮
			ResourceType type = bo.getResourceType();
			if(type != null)
			{
				if(!ResourceType.MENU_CODE.equals(type.getCode()))
				{//按钮加入map
					List<CommonDto> buttonList = map.get(bo.get_parentId());
					if(buttonList == null)
					{
						buttonList = new ArrayList<>();
					}
					CommonDto dto = new CommonDto();
					dto.setId(bo.getId());
					dto.setName(bo.getName());
					dto.setStr1(bo.isChecked()?"1":"0");
					buttonList.add(dto);
					map.put(bo.get_parentId(), buttonList);
				}
				else
				{//菜单加入列表
					menuList.add(bo);
				}
			}
		}
		
		//按钮和菜单挂接
		for(Resource bo:menuList)
		{
			bo.setSon(map.get(bo.getId()));
		}
		Result result = new Result();
		result.setRows(menuList);
		return result;
	}


	/**
	 * 保存权限配置
	 */
	@RequestMapping("/editAuth")
	@ResponseBody
	public Message editAuth(Long roleId,Long ids[]) {
		Message rm = new Message();
		try {
			Role bo = service.findOne(roleId);

			if(ids!=null && ids.length>0)
			{
				List<Long> idList = new ArrayList<>();
				for(Long id:ids)
				{
					idList.add(id);
				}
				List<Resource> resourceList = resourceService.findAll(idList);
				bo.setResourceList(resourceList);
			}
			else
			{
				bo.setResourceList(null);
			}

			service.save(bo);
			
			//更新内存权限
			AuthInterceptor.setAuthMap(service.getAuthMap());
			
			rm.setMsg("保存成功！");
			rm.setCode(Message._SUCCESS);
		} catch (Exception e) {
			rm.setMsg("保存失败，异常信息：<br/>" + e.toString());
			rm.setCode(Message._ERROR);
			e.printStackTrace();
		}
		return rm;
	}
	

	/**
	 * 删除
	 */
	@RequestMapping("/delete")
	@ResponseBody
	public Message delete(Long ids[]) {
		Message rm = new Message();
		try {
			
			//处理对用户中 roleNames的更新
			List<Long> idList = new ArrayList<>();
			for(Long id:ids)
			{
				idList.add(id);
			}
			Set<User> needUpdateSet =new HashSet<>(); //所有需要更新的用户
			List<Role>  list = service.findAll(idList);
			for(Role bo:list)
			{
				needUpdateSet.addAll(bo.getUserList());
			}
			
			//删除
			for(Long id:ids)
			{
				service.delete(id);
			}
			
			//更新
			this.updateUserRoleNames(needUpdateSet);
			
			rm.setMsg("删除成功！");
			rm.setCode(Message._SUCCESS);
		} catch (Exception e) {
			rm.setMsg("删除失败，异常信息：<br/>" + e.toString());
			rm.setCode(Message._ERROR);
			e.printStackTrace();
		}
		return rm;
	}

	/**
	 * 更新一批用户的 roleNames属性
	 */
	private void updateUserRoleNames(Set<User> needUpdateSet)
	{
		for(User user:needUpdateSet)
		{
			List<Role> roleList = user.getRoleList();
			StringBuilder roleNames = new StringBuilder();
			for(Role bo:roleList)
			{
				roleNames.append(bo.getName()+"，");
			}
			if(roleNames.length()>0)
			{
				user.setRoleNames(xx.delEnd(roleNames.toString(), "，"));
			}
			else
			{
				user.setRoleNames(null);
			}
		}
		userService.save(needUpdateSet);
	}
	
	/**
	 * 详情页面
	 */
	@RequestMapping("/detailPage")
	public String detailPage(Model model, Long id) {
		model.addAttribute("bo", service.findOne(id));
		return this.getPath()+"detail";
	}
	

	/**
	 * 导出Excel
	 * @throws Exception 
	 */
	@RequestMapping("/exportExcel")
	public void exportExcel(HttpServletResponse response,RoleVo vo,String type) throws Exception {
		
		File file = new File("aaa.xls");
		jxl.write.WritableWorkbook book = Workbook.createWorkbook(file); //工作薄

		List<Role> allDataList=service.QueryExcelData(vo); //取得导出数据
		ExcelBook<Role> excelBook = this.buildExcelData(allDataList, type); //按维度进行数据加工
		String bookName = excelBook.getName(); //Excel文件名称
		List<ExcelSheet<Role>> sheetList = excelBook.getSheetList(); //各Sheet列表
		if(sheetList!=null && sheetList.size() > 0)
		{
			for(ExcelSheet<Role> excelSheet:sheetList)
			{
				String sheetName = excelSheet.getName(); //名称
				List<Role> oneList = excelSheet.getDataList(); //数据列表
				
				jxl.write.WritableSheet sheet = book.createSheet(sheetName, 0); //工作表
				
				//设置行高
				sheet.getSettings().setDefaultRowHeight(350); //设置所有行默认行高
				sheet.setRowView(0, 700);//第1行 高度
				sheet.setRowView(1, 400);//第2行 高度
				
				//设置个别列宽
				//sheet.setColumnView(2, 12);//宽度设置
				
				//定义格式
				//主标题格式
				WritableCellFormat formatterTitle= new WritableCellFormat(); //标题格式
				formatterTitle.setAlignment(Alignment.CENTRE);//水平对齐
				formatterTitle.setVerticalAlignment(VerticalAlignment.CENTRE);//垂直对齐
				//WritableFont font = new WritableFont(WritableFont.createFont("ＭＳ Ｐゴシック"), 18, WritableFont.BOLD, false); //黑体
				WritableFont font = new WritableFont(WritableFont.TAHOMA, 18, WritableFont.BOLD, false);
				formatterTitle.setFont(font);
				
				//列标题格式
				WritableCellFormat formatterColumnTitle= new WritableCellFormat(); //列标题格式
				formatterColumnTitle.setAlignment(Alignment.CENTRE);//水平对齐
				formatterColumnTitle.setVerticalAlignment(VerticalAlignment.CENTRE);//垂直对齐
				formatterColumnTitle .setBackground(Colour.GRAY_25);//背景色
				formatterColumnTitle.setBorder(Border.ALL, BorderLineStyle.THIN);//边框线  所有边框 细线

				//普通内容格式
				WritableCellFormat formatterCon= new WritableCellFormat(); //内容格式
				formatterCon.setAlignment(Alignment.CENTRE);//水平对齐
				formatterCon.setVerticalAlignment(VerticalAlignment.CENTRE);//垂直对齐
				formatterCon.setBorder(Border.ALL, BorderLineStyle.THIN);//边框线  所有边框 细线
				
				//合计行格式
				WritableCellFormat formatterSum= new WritableCellFormat(); //合计格式
				formatterSum.setAlignment(Alignment.CENTRE);//水平对齐
				formatterSum.setVerticalAlignment(VerticalAlignment.CENTRE);//垂直对齐
				formatterSum.setBorder(Border.ALL, BorderLineStyle.THIN);//边框线  所有边框 细线
				WritableFont font_sum = new WritableFont(WritableFont.TAHOMA, 10, WritableFont.BOLD, false);
				formatterSum.setFont(font_sum);
				
				//输出标题
				sheet.mergeCells(0, 0, 2, 0); //合并单元格（标题）
				sheet.addCell(creatLabel(0,0,"角色管理（"+sheetName+"）",formatterTitle));

				//输出列标题
				int rowNum=1; //行号
				int columnNum=0; //列号
				
				sheet.addCell(creatLabel(rowNum,columnNum++,"序号",formatterColumnTitle));
				sheet.addCell(creatLabel(rowNum,columnNum++,"名称",formatterColumnTitle));
				sheet.addCell(creatLabel(rowNum,columnNum++,"排序号",formatterColumnTitle));
				
				//合计项
			
				if(oneList != null && oneList.size() > 0)
				{
					//SimpleDateFormat formatterDate = new SimpleDateFormat("yyyy-MM-dd"); //日期格式化
					//SimpleDateFormat formatterTime = new SimpleDateFormat("yyyy-MM-dd HH:mm"); //时间格式化
					//SimpleDateFormat formatterTime2 = new SimpleDateFormat("yyyy-MM-dd HH:mm"); //时间格式化2
					
					//展示数据
					String nameStr = ""; // 名称
					String orderNumStr = ""; // 排序号
					
					for(int i = 0; i < oneList.size(); i++)
			    	{
						Role bo = oneList.get(i); 
						rowNum++;
						columnNum=0;
						
						//展示数据初始化
						nameStr = ""; // 名称
						orderNumStr = ""; // 排序号
						
						//展示数据赋值
						if(bo.getName() != null){	nameStr = bo.getName().toString();	} //名称
	           		
						if(bo.getOrderNum() != null){	orderNumStr = bo.getOrderNum().toString();	} //排序号
	           		
						
						
						//输出一行数据
			    		sheet.addCell(creatLabel(rowNum,columnNum++,(i+1)+"",formatterCon)); 
			    		sheet.addCell(creatLabel(rowNum,columnNum++,nameStr ,formatterCon)); // 名称
			    		sheet.addCell(creatLabel(rowNum,columnNum++,orderNumStr ,formatterCon)); // 排序号
			    		
			    		//合计项累加
			    	}
					
					//表格增加合计项
					rowNum++;
					columnNum = 0;
					sheet.setRowView(rowNum, 400);//合计行 高度
		    		
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"",formatterSum)); 
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"" ,formatterSum)); // 名称
		    		sheet.addCell(creatLabel(rowNum,columnNum++,"" ,formatterSum)); // 排序号
    		
				}
			}
		}
		
		//-------------------------------

		book.write();
		book.close();

		FileInputStream f = new FileInputStream(file);
		byte[] fb = new byte[f.available()];
		f.read(fb);
		response.setHeader("Content-disposition", "attachment; filename=" + new String((bookName + ".xls").getBytes("gb2312"), "iso8859-1"));
		ByteArrayInputStream bais = new ByteArrayInputStream(fb);
		int b;
		while ((b = bais.read()) != -1)
		{
			response.getOutputStream().write(b);
		}
		response.getOutputStream().flush();
		f.close();
		
	}
	
	private Label creatLabel(int rowNum,int columnNum,String con,WritableCellFormat formatter) //行，列，内容 ，格式化
	{  
		 return new Label(columnNum, rowNum, con,formatter);   
	}  
	
	/**
	 * 从不同维度，构建Excel导出所需要的数据
	 */
	private ExcelBook<Role> buildExcelData(List<Role> list,String exportType)
	{
		ExcelBook<Role> book = new ExcelBook<Role>();
		
		
		if("all".equals(exportType))
		{//不分表
			book.setName("角色管理");
		}

		//根据维度（sheetName）不同，对数据分表
		Map<String,List<Role>> map =new HashMap<String,List<Role>>(); 
		String sheetName = null;
		for(Role bo:list)
		{
		
	
			if("all".equals(exportType))
			{//不分表
				sheetName="全部";
			}
			
			List<Role> dataList = map.get(sheetName);
			if(dataList==null)
			{
				dataList = new ArrayList<>();
			}
			dataList.add(bo);
			map.put(sheetName, dataList);
		}
		
		//转换Map,得到数据表列表
		List<ExcelSheet<Role>> sheetList = new ArrayList<>();
		for (Map.Entry<String, List<Role>> m : map.entrySet()) 
		{
			ExcelSheet<Role> sheet = new ExcelSheet<Role>();
			sheet.setName(m.getKey());
			sheet.setDataList(m.getValue());
			sheetList.add(sheet);
		} 
		
		if(sheetList.size()==0)
		{
			ExcelSheet<Role> sheet = new ExcelSheet<Role>();
			sheet.setName("全部");
			sheet.setDataList(new ArrayList<Role>());
			sheetList.add(sheet);
		}
		
		book.setSheetList(sheetList);
		
		return book;
	}
	
}
